﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace MMDemo
{
    public partial class BinTreeBrowseForm : Form
    {
        public BinTreeBrowseForm()
        {
            InitializeComponent();
            String path = Application.StartupPath;
            NodeBmp = (Bitmap)Image.FromFile(path + "/image/ball_four.png");
        }

        private int NodeSize = 30;
        private int NodeChildOffset = 80;
        private Bitmap NodeBmp = null;
        private int num = 0;//二叉树的结点数量
        private const int MAX_NUM = 16;//二叉树最大结点数

        private void RandBtn_Click(object sender, EventArgs e)
        {
            GlobalBinTree.treeroot = null;
            num = 0;
            RandCreateTree(ref GlobalBinTree.treeroot, 0);
            this.GraphShowPictrueBox.Refresh();
        }

        Random ran = new Random();
        private void RandCreateTree(ref BinTreeNode root,int n)
        {
            int IsPresence = ran.Next(100 - n * 5);
            if (IsPresence==0)
            {
               root = null;
            }
            else if (num < MAX_NUM)
            {
                root = new BinTreeNode();
                ++num;
                root.data = ((char)(ran.Next(26) + 65)).ToString();
                if (ran.Next(4) != 3 && n < 4)
                {
                    RandCreateTree(ref root.lChild, n + 1);
                }
                if (ran.Next(4) != 3 && n < 4)
                {
                    RandCreateTree(ref root.rChild, n + 1);
                }
               
            }

        }

        private void GraphShowPictrueBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            if (GlobalBinTree.treeroot!=null)
            {
                GlobalBinTree.treeroot.x = GraphShowPictrueBox.Width / 2;//
                GlobalBinTree.treeroot.y = GraphShowPictrueBox.Height / 5;//
            }
            ShowGraphics(e.Graphics, ref GlobalBinTree.treeroot, 1, TreeHeight(ref GlobalBinTree.treeroot));
        }


        public int TreeHeight(ref BinTreeNode btn)
        {
            if (btn == null) return 0;	//空树高度为0
            else
            {
                int i = TreeHeight(ref btn.lChild);
                int j = TreeHeight(ref btn.rChild);
                return (i < j) ? j + 1 : i + 1;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        /// <param name="btn"></param>
        /// <param name="n">二叉树的该结点所在的层次，根结点为1</param>
        private void ShowGraphics(Graphics g, ref BinTreeNode btn, int n,int m)
        {
            NodeSize = (int)(GraphShowPictrueBox.Width / (Math.Pow(2, m - 1) + 1.0));
            NodeSize = (NodeSize > 40 ? 40 : NodeSize);
            int y = (int)(GraphShowPictrueBox.Height * 1.0 / (m + 1));
            int x = (int)(GraphShowPictrueBox.Width / Math.Pow(2, n));
            if (btn != null)
            {
                if (n == 1)
                {
                    btn.x = x;
                    btn.y = y;
                }
                if (btn.lChild != null)
                {
                    btn.lChild.x = btn.x - x / 2;
                    btn.lChild.y = btn.y + y;
                    g.DrawLine(new Pen(Color.Blue, 3), new Point(btn.x, btn.y), new Point(btn.lChild.x, btn.lChild.y));
                    ShowGraphics(g, ref btn.lChild, n + 1, m);
                }
                if (btn.rChild != null)
                {
                    btn.rChild.x = btn.x + x / 2;
                    btn.rChild.y = btn.y + y;
                    g.DrawLine(new Pen(Color.Blue, 3), new Point(btn.x, btn.y), new Point(btn.rChild.x, btn.rChild.y));
                    ShowGraphics(g, ref btn.rChild, n + 1, m);
                }

                g.DrawImage(NodeBmp, btn.x - NodeSize / 2, btn.y - NodeSize / 2, NodeSize, NodeSize);
                g.DrawString(btn.data, new Font("微软雅黑", 13), Brushes.Yellow, btn.x - NodeSize / 2 + NodeSize / 5, btn.y - NodeSize / 2 + NodeSize / 5);
            }
            
        }

        private void OKBtn_Click(object sender, EventArgs e)
        {
            if (0 == num)
            {
                MessageBox.Show("二叉树没有生成，请继续生成！");
                return;
            }
            PublicDataClass.IsInit = true;
            this.Close();
        }
        protected override void WndProc(ref   Message m)
        {
            const int WM_SYSCOMMAND = 0x0112;
            const int SC_CLOSE = 0xF060;
            if (m.Msg == WM_SYSCOMMAND && (int)m.WParam == SC_CLOSE)
            {
                PublicDataClass.IsInit = false;
                this.Close();
                return;
            }
            base.WndProc(ref m);
        }
    }
}
